/*
* Copyright © Shanghai Awinic Technology Co., Ltd. 2020-2020. All rights reserved.
* Description: Flash driver related library function files.
* Date： 20201126
* Awinic_Version： aw_soc_driver_v1.0.0
*/
#include "compile_option.h"
#ifdef AW_86802

#include "aw8680x_global.h"

/* The following time units are NS */
#define AW_SYS_TIM			(1000000000 / AW_SYS_CLOCK)	// Simulated clock frequency 50Mhz ,Clock cycle = 1/f,Clock cycle time =20ns
#define TNVS_TIM			(6000 / AW_SYS_TIM)			// TNVC_TIM = 6us/20ns =300
#define TPGS_TIM			(6000 / AW_SYS_TIM)			// = 6us/20ns =300	  5-6.5us  Value 6us
#define TPROG_TIM			(7000 / AW_SYS_TIM)			// = 7us/20ns =350	  6-7.5us  Value 7us
#define TRCV_PGM_TIM		(5000 / AW_SYS_TIM)			// = 5us/20ns =250	  5us	  Value 5us
#define TRCV_SECTOR_TIM		(50000 / AW_SYS_TIM)		// = 50us/20ns =2500	50us	 Value 50us
#define TRCV_CHIP_TIM		(200000 / AW_SYS_TIM)		// = 200us/20ns =10000  200us	Value 200us
#define TRW_TIM				(100 / AW_SYS_TIM)			// = 100ns/20ns =5	  100ns	Value 100ns
#define TERASE_SECTOR_TIM	(4500000 / AW_SYS_TIM)		// = 4.5ms/20ns =225000 4-5ms	Value 4.5ms
#define TERASE_CHIP_TIM		(30000000 / AW_SYS_TIM)		// = 30ms/20ns =1500000 20-40ms  Value 30ms
#define TWAKEUP_TIM			(10000 / AW_SYS_TIM)		// = 10us/20ns =500	 10us   Value 10us

#define FLASH_PRGOM_TIMEOUT			((AW_S32)(40000 / (10 * AW_SYS_TIM)))		// Each programming time is about 35us,40us here.
#define FLASH_ER_SECTOR_TIMEOUT		((AW_S32)(6000000 / (10 * AW_SYS_TIM)))		// Sector erase time is about 5ms, 6ms here
#define FLASH_ER_CHIP_TIMEOUT		((AW_S32)(50000000 / (10 * AW_SYS_TIM)))	// chip erase time is about 40ms, 50ms here

/**
  * @brief  Flash put 32bit data into the specified address function
  * @param  u8_addr (address), u32_data (data)
  * @retval None
  */
#ifndef AWINIC_IAR
static void flash_set_u32_fun(AW_U8 *p_u8_addr, AW_U32 u32_data)
#else
__ramfunc static void flash_set_u32_fun(AW_U8 *p_u8_addr, AW_U32 u32_data)
#endif
{
	if (p_u8_addr == AW_NULL) {
		return;
	}

	/* Put 32bit data into the specified address according to the small end mode */
	p_u8_addr[0] = (AW_U8)(u32_data >> 0);
	p_u8_addr[1] = (AW_U8)(u32_data >> 8);
	p_u8_addr[2] = (AW_U8)(u32_data >> 16);
	p_u8_addr[3] = (AW_U8)(u32_data >> 24);
}

extern void hal_delay_us(unsigned int n);

void aw_close_device_irq(void)
{
	protect_unlock();
	PWR->SWDT_LOAD_EN = 1;
	PWR->SWDT_EN = 0x00; // open swdt time
	protect_lock();
	hal_delay_us(100);
}

void aw_open_device_irq(void)
{
	protect_unlock();
	PWR->SWDT_LOAD_EN = 0;
	PWR->SWDT_EN = 0x01; // open swdt time
	protect_lock();
}

/**
  * @brief  32bit data acquisition function
  * @param  u8_addr (address)
  * @retval AW_U32 data
  */
#ifndef AWINIC_IAR
static AW_U32 flash_get_u32_fun(AW_U8 *p_u8_addr)
#else
__ramfunc static AW_U32 flash_get_u32_fun(AW_U8 *p_u8_addr)
#endif
{
	AW_U32 u32_data = AW_NUM_NULL;

	u32_data = (p_u8_addr[0] << 0) + (p_u8_addr[1] << 8) +
				(p_u8_addr[2] << 16) + (p_u8_addr[3] << 24);

	return u32_data;
}

/**
  * @brief  Flash state judgment function
  * @param  None
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_get_status(void)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_get_status(void)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	/* Judgment flash status */
	if ((FMC->ISP_GO & FLASH_ISPGO) == FLASH_ISPGO) {
		status = FLASH_BUSY;
	} else {
		status = FLASH_COMPLETE;
	}

	/* Return the FLASH Status */
	return status;
}

/**
  * @brief  Flash state timeout judgment function
  * @param  AW_S32 timeout (Timeout time parameter)
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
static FLASH_STATUS_TYPE_E flash_wait_last_operation(AW_S32 timeout)
#else
__ramfunc static FLASH_STATUS_TYPE_E flash_wait_last_operation(AW_S32 timeout)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	/* Check for the FLASH Status */
	status = flash_get_status();

	/* Wait for a FLASH operation to complete or a TIMEOUT to occur */
	while ((status == FLASH_BUSY) && (timeout > AW_NUM_NULL)) {
		status = flash_get_status();
		timeout--;
	}

	if (timeout <= AW_NUM_NULL ) {
		status = FLASH_TIMEOUT;
	}

	/* Return the operation status */
	return status;
}

/**
  * @brief  Flash sector erase function
  * @param  addr_dat (Any address in sector)
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_erase(AW_U32 addr_dat)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_erase(AW_U32 addr_dat)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure flash register as sector erase mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD &= ISPCMD_NVR_DIS;
		FMC->ISP_CMD |= ISPCMD_ERASE;
		FMC->ISP_ADR = addr_dat;
		FMC->T_RCV = TRCV_SECTOR_TIM;
		FMC->T_ERASE = TERASE_SECTOR_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_ER_SECTOR_TIMEOUT);
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  Flash chip erase function
  * @param  None
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_erase_chip(void)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_erase_chip(void)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	AW_U32 i = 0;
	for (i = 0; i < FLASH_SECTOR_NUM; i++) {
		status = flash_erase(FLASH_BASE + FLASH_SECTOR_SIZE * i);
	}

	return status;
}

/**
  * @brief  NVR Flash sector erase function
  * @param  addr_dat (Any address in sector)
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_erase_nvr(AW_U32 addr_dat)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_erase_nvr(AW_U32 addr_dat)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure flash register as nvr sector erase mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD |= ISPCMD_NVR_EN;
		FMC->ISP_CMD |= ISPCMD_ERASE;
		FMC->ISP_ADR = addr_dat;
		FMC->T_RCV = TRCV_SECTOR_TIM;
		FMC->T_ERASE = TERASE_SECTOR_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_ER_SECTOR_TIMEOUT);
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  NVR Flash single write function
  * @param  addr_dat (address) ,data_dat(data)
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_write_single_nvr(AW_U32 addr_dat, AW_U32 data_dat)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_write_single_nvr(AW_U32 addr_dat, AW_U32 data_dat)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure nvr flash register as single write mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD |= ISPCMD_NVR_EN;
		FMC->ISP_CMD |= ISPCMD_WRITE;
		FMC->ISP_ADR = addr_dat;
		FMC->ISP_WDAT0 = data_dat;
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT);
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  NVR Flash continuous writing function
  * @param  addr_dat (address), data_dat(data), reg_data_len(length)
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_write_many_nvr(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_write_many_nvr(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#endif
{
	AW_U32 i = AW_NUM_NULL;
	AW_U32 flash_data = AW_NUM_NULL;
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	if (p_data_dat == AW_NULL) {
		return FLASH_FALL;
	}

	reg_data_len = reg_data_len / ADDR_DATA_LEN;
	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure nvr flash register as continuous writing mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD |= ISPCMD_NVR_EN;
		FMC->ISP_CMD |= FLASH_LENGTH_NUM(reg_data_len);
		FMC->ISP_CMD |= ISPCMD_WRITE;
		FMC->ISP_ADR = addr_dat;
		for (i = AW_NUM_NULL; i < reg_data_len; i++) {
			flash_data = flash_get_u32_fun(&p_data_dat[FLASH_REG_DATA_LEN * i]);
			FMC->ISP_WDAT[i] = flash_data;
		}
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT * reg_data_len);
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  NVR Flash single read function
  * @param  addr_dat (address) ,data_dat(data)
  * @retval FLASH_STATUS_TYPE_E status
  */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_read_single_nvr(AW_U32 addr_dat, AW_U32 *p_data_dat)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_read_single_nvr(AW_U32 addr_dat, AW_U32 *p_data_dat)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	if (p_data_dat == AW_NULL) {
		return FLASH_FALL;
	}

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure nvr flash register as single read mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD |= ISPCMD_NVR_EN;
		FMC->ISP_CMD |= ISPCMD_READ;
		FMC->ISP_ADR = addr_dat;
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT);
		*p_data_dat = FMC->ISP_RDAT0;
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  NVR Flash continuous reading function
  * @param  addr_dat (address), data_dat(data), reg_data_len(length)
 */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_read_many_nvr(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_read_many_nvr(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#endif
{
	AW_U32 i = AW_NUM_NULL;
	AW_U32 flash_data = AW_NUM_NULL;
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	if (p_data_dat == AW_NULL) {
		return FLASH_FALL;
	}

	reg_data_len = reg_data_len / ADDR_DATA_LEN;
	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure nvr flash register as continuous reading mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD |= ISPCMD_NVR_EN;
		FMC->ISP_CMD |= FLASH_LENGTH_NUM(reg_data_len);
		FMC->ISP_CMD |= ISPCMD_READ;
		FMC->ISP_ADR = addr_dat;
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT * reg_data_len);
		for (i = AW_NUM_NULL; i < reg_data_len; i++) {
			flash_data = FMC->ISP_RDAT[i];
			flash_set_u32_fun(&p_data_dat[FLASH_REG_DATA_LEN * i], flash_data);
		}
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  Flash single write function
  * @param  addr_dat (address), data_dat(data)
  * @retval FLASH_STATUS_TYPE_E status
 */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_write_single(AW_U32 addr_dat, AW_U32 data_dat)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_write_single(AW_U32 addr_dat, AW_U32 data_dat)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure flash register as single read mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD &= ISPCMD_NVR_DIS;
		FMC->ISP_CMD |= ISPCMD_WRITE;
		FMC->ISP_ADR = addr_dat;
		FMC->ISP_WDAT0 = data_dat;
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT);
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  Flash continuous writing function
  * @param  addr_dat (address), data_dat(data), reg_data_len(length)
  * @retval FLASH_STATUS_TYPE_E status
 */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_write_many(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_write_many(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#endif
{
	AW_U32 i = AW_NUM_NULL;
	AW_U32 flash_data = AW_NUM_NULL;
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	if (p_data_dat == AW_NULL) {
		return FLASH_FALL;
	}

	if (reg_data_len % ADDR_DATA_LEN)
	{
		reg_data_len = reg_data_len / ADDR_DATA_LEN + 1;
	}
	else
	{
		reg_data_len = reg_data_len / ADDR_DATA_LEN;
	}

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure flash register as continuous writing mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD &= ISPCMD_NVR_DIS;
		FMC->ISP_CMD |= FLASH_LENGTH_NUM(reg_data_len);
		FMC->ISP_CMD |= ISPCMD_WRITE;
		FMC->ISP_ADR = addr_dat;
		for (i = AW_NUM_NULL; i < reg_data_len; i++) {
			flash_data = flash_get_u32_fun(&p_data_dat[FLASH_REG_DATA_LEN * i]);
			FMC->ISP_WDAT[i] = flash_data;
		}
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT * reg_data_len);
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  Flash single read function
  * @param  addr_dat (address), data_dat(data)
  * @retval FLASH_STATUS_TYPE_E status
 */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_read_single(AW_U32 addr_dat, AW_U32 *p_data_dat)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_read_single(AW_U32 addr_dat, AW_U32 *p_data_dat)
#endif
{
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	if (p_data_dat == AW_NULL) {
		return FLASH_FALL;
	}

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure flash register as single read mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD &= ISPCMD_NVR_DIS;
		FMC->ISP_CMD |= ISPCMD_READ;
		FMC->ISP_ADR = addr_dat;
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT);
		*p_data_dat = FMC->ISP_RDAT0;
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  Flash continuous reading function
  * @param  addr_dat (address), p_data_dat(data), reg_data_len(length)
  * @retval FLASH_STATUS_TYPE_E status
 */
#ifndef AWINIC_IAR
FLASH_STATUS_TYPE_E flash_read_many(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#else
__ramfunc FLASH_STATUS_TYPE_E flash_read_many(AW_U32 addr_dat, AW_U8 *p_data_dat, AW_U8 reg_data_len)
#endif
{
	AW_U32 i = AW_NUM_NULL;
	AW_U32 flash_data = AW_NUM_NULL;
	FLASH_STATUS_TYPE_E status = FLASH_COMPLETE;

	if (p_data_dat == AW_NULL) {
		return FLASH_FALL;
	}

	if (reg_data_len % ADDR_DATA_LEN)
	{
		reg_data_len = reg_data_len / ADDR_DATA_LEN + 1;
	}
	else
	{
		reg_data_len = reg_data_len / ADDR_DATA_LEN;
	}

	protect_unlock();
	/* Wait for last operation to be completed */
	status = flash_wait_last_operation(FLASH_ER_CHIP_TIMEOUT);

	/* If idle, configure flash register as continuous reading mode */
	if (status == FLASH_COMPLETE) {
		FMC->ISP_CR |= FLASH_EN; // Enable isp function
		FMC->ISP_CMD = ISPCMD_DIS;
		FMC->ISP_CMD &= ISPCMD_CHIP_DIS;
		FMC->ISP_CMD &= ISPCMD_NVR_DIS;
		FMC->ISP_CMD |= FLASH_LENGTH_NUM(reg_data_len);
		FMC->ISP_CMD |= ISPCMD_READ;
		FMC->ISP_ADR = addr_dat;
		FMC->T_RCV = TRCV_PGM_TIM;
		FMC->ISP_GO = FLASH_ISPGO;
		status = flash_wait_last_operation(FLASH_PRGOM_TIMEOUT * reg_data_len);
		for (i = AW_NUM_NULL; i < reg_data_len; i++) {
			flash_data = FMC->ISP_RDAT[i];
			flash_set_u32_fun(&p_data_dat[FLASH_REG_DATA_LEN * i], flash_data);
		}
		FMC->ISP_CR &= FLASH_CLOSE; // Enable isp function
	}
	protect_lock();

	return status;
}

/**
  * @brief  Flash time parameter configure function
  * @param  None
  * @retval FLASH_STATUS_TYPE_E status
 */
#ifndef AWINIC_IAR
static void flash_tim_config(void)
#else
__ramfunc static void flash_tim_config(void)
#endif
{
	protect_unlock();
	FMC->T_NVS = TNVS_TIM;
	FMC->T_PGS = TPGS_TIM;
	FMC->T_PROG = TPROG_TIM;
	FMC->T_RW = TRW_TIM;
	FMC->T_WAKEUP = TWAKEUP_TIM;
	protect_lock();
}

/**
  * @brief  Flash initialization function
  * @param  None
  * @retval None
  */
#ifndef AWINIC_IAR
void flash_init(void)
#else
__ramfunc void flash_init(void)
#endif
{
	flash_clk_init();
	flash_tim_config();
}

#endif